Skip to content

fix: remediate 2026-07-13 external audit findings (lexical retrieval, privacy, upload, CSP, a11y)#582

Merged
BigSimmo merged 10 commits into
mainfrom
claude/audit-remediation-2026-07-13
Jul 13, 2026
Merged

fix: remediate 2026-07-13 external audit findings (lexical retrieval, privacy, upload, CSP, a11y)#582
BigSimmo merged 10 commits into
mainfrom
claude/audit-remediation-2026-07-13

Conversation

@BigSimmo

Copy link
Copy Markdown
Owner

Summary

Remediates the code-addressable findings of the 2026-07-13 external repository audit (verified against current main before implementation; every finding re-confirmed with file/line evidence first).

  • fix(db) — five migrations (2026071310000020260713104000):
    • Rewrite match_document_chunks_text around two GIN-indexable candidate branches (chunk tsv probe + title tsv fan-out, unioned by chunk id) replacing the OR-across-relations predicate that sequential-scanned all ~70k chunks (~17s warm on live; audit finding 1). Identical contract/scores/caps/grants; the _v2 wrapper inherits the speedup. Parity + plan + timing harness at scripts/sql/lexical-rpc-parity-check.sql: 10 query shapes identical to the legacy body, no document_chunks seq scan, 8.3× faster on a 30k synthetic corpus.
    • Pin search_path on retrieval_owner_matches_v2 (the one remaining function_search_path_mutable advisor warning; finding 6).
    • Revoke anon/authenticated future-object default privileges for role supabase_admin with a guarded fallback and in-migration future-object probes (finding 7).
    • Scrub pre-HMAC plaintext query text (rag_queries, rag_query_misses, rag_retrieval_logs) with salted irreversible placeholders; delete legacy raw-keyed rag_response_cache rows (finding 5). Live counts confirmed pre-apply: 230 / 10 / 84 / 0.
    • Validate the three content_not_blank constraints (zero violating rows on live; finding 12).
  • fix(privacy) — owner-scope the recent-queries read in the standalone search shell and purge the legacy unscoped localStorage key on both surfaces without migrating it (finding 4). New unit suite + @critical Playwright regression.
  • fix(upload) — structural OOXML/PDF admission validation via jszip (content types, required main part, macro rejection, non-hyperlink external-relationship rejection, entry/size/ratio caps, PDF %%EOF; finding 10).
  • fix(security) — drop api.openai.com from CSP connect-src (server-side-only provider calls; finding 12).
  • fix(a11y) — explicit accessible names on split-pane tool-card buttons (finding 8 sub-item).

Verification

  • npm run verify:pr-local (format, lint, typecheck, 1953 unit tests, production build + client-bundle secret scan)
  • npm run verify:ui scope covered: full @critical Chromium gate (10/10) + targeted regression specs for every UI change; full 142-test stable regression set green on the sibling CI-gate branch
  • npm run eval:rag:offline (265/265)
  • npm run eval:retrieval:quality — 36/36 PASS pre-apply baseline (content_mrr@10 = 0.9103); the DB function only changes at live apply, so the eval will be re-run immediately after the migrations are applied (must stay 36/36; per-case lexical latencies of 17–54s in the baseline are the audited defect and should collapse)
  • Migration replay: schema.sql replayed from scratch twice in clean Docker Postgres (drift-manifest regen + parity container); CI db-reset-verify replays the migration chain
  • npm run check:supabase-project (targets Clinical KB Database / sjrfecxgysukkwxsowpy)

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use (no answer-policy changes; retrieval rewrite is result-identical, proven by the parity harness)
  • No patient-identifiable document workflow was introduced or expanded (this PR removes PHI-at-rest surfaces: legacy query-text scrub + unscoped browser-storage purge)
  • Supabase target remains Clinical KB Database (sjrfecxgysukkwxsowpy)
  • Service-role keys and private document access remain server-only (CSP tightened; retrieval RPC grants unchanged, service-role-only)
  • Demo/synthetic content remains clearly separated from real clinical sources
  • Source metadata, review status, and outdated/unknown-source behaviour remain conservative (untouched)
  • No clinical decision-support behaviour change (retrieval results are byte-identical; only latency improves), so no new TGA SaMD impact

Notes

  • Post-merge live steps (tracked): apply the five migrations to live with history stamps matching the repo filenames, re-run eval:retrieval:quality (36/36), re-run Supabase advisors (expect zero), verify scrub counts are 0, npm run check:drift, trigger the Eval Canary. The supabase_admin default-privilege migration degrades to a WARNING on hosted if postgres cannot act for the role; the probe block reports it.
  • The invalid storage.idx_objects_bucket_id_name_lower index (audit finding 12) has already been repaired live via REINDEX; zero invalid indexes remain.

🤖 Generated with Claude Code

BigSimmo and others added 5 commits July 13, 2026 19:23
- Rewrite match_document_chunks_text around two GIN-indexable candidate
  branches (chunk tsv + title tsv fan-out, unioned by chunk id) instead of
  the OR-across-relations predicate that sequential-scanned every chunk
  (~17s warm on live; audit finding 1). Contract, scores, caps, ordering,
  and grants unchanged; the _v2 wrapper inherits the speedup. Parity/plan/
  timing harness: scripts/sql/lexical-rpc-parity-check.sql (10 query shapes
  identical; no document_chunks seq scan; 8.3x faster on a 30k synthetic
  corpus).
- Pin search_path on retrieval_owner_matches_v2 (advisor
  function_search_path_mutable; finding 6).
- Revoke anon/authenticated future-object default privileges for role
  supabase_admin with guarded fallback and in-migration probe verification
  (finding 7); postgres-role defaults were already covered.
- Scrub pre-HMAC plaintext query text in rag_queries, rag_query_misses and
  rag_retrieval_logs with salted irreversible placeholders; delete legacy
  raw-keyed rag_response_cache rows (finding 5).
- Validate the three content_not_blank CHECK constraints (zero violating
  rows on live) so they are enforced rather than NOT VALID (finding 12).

schema.sql mirrored, drift manifest regenerated from a clean scratch
replay, schema/drift tests extended.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d key

The standalone search shell still read the unscoped
clinical-kb-recent-queries localStorage key, so a historical clinical query
written by an older build could resurface for whoever used the browser next
(2026-07-13 audit, finding 4). The shell now reads the owner-scoped
sessionStorage key with the same owner derivation as the dashboard, and both
surfaces purge the legacy unscoped keys on mount without migrating them (the
original owner cannot be established). Covered by a unit suite for the shared
storage module and a @critical Playwright regression that seeds the legacy
value and asserts it is never rendered and gets deleted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signature checks only proved the first four bytes: any PK-prefixed stream
passed as DOCX/XLSX and any %PDF-prefixed stream passed as PDF (2026-07-13
audit, finding 10). Uploads now must be readable ZIP packages with
[Content_Types].xml and the expected main part, no macro content
(vbaProject.bin or macroEnabled content types), no non-hyperlink external
relationships, safe entry paths, and bounded entry count/decompressed
size/compression ratio; PDFs must carry an %%EOF trailer. Existing route
tests updated to structurally minimal valid PDF fixtures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
OpenAI calls are server-side only; allowing the browser to reach the
provider origin needlessly widened the exfiltration surface (2026-07-13
audit, finding 12). Tests now assert the provider origin stays out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The split-pane tool cards and wide-section rows exposed only concatenated
card text as their accessible name while their Link siblings carried
explicit labels (2026-07-13 audit, finding 8 sub-item). Button variants now
carry "Preview <tool>" labels; the collapse spec asserts the explicit name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@supabase

supabase Bot commented Jul 13, 2026

Copy link
Copy Markdown

Updates to Preview Branch (claude/audit-remediation-2026-07-13) ↗︎

Deployments Status Updated
Database Mon, 13 Jul 2026 13:43:45 UTC
Services Mon, 13 Jul 2026 13:43:45 UTC
APIs Mon, 13 Jul 2026 13:43:45 UTC

Tasks are run on every commit but only new migration files are pushed.
Close and reopen this PR if you want to apply changes from existing seed or migration files.

Tasks Status Updated
Configurations Mon, 13 Jul 2026 13:43:47 UTC
Migrations Mon, 13 Jul 2026 13:43:49 UTC
Seeding Mon, 13 Jul 2026 13:43:50 UTC
Edge Functions Mon, 13 Jul 2026 13:43:51 UTC

View logs for this Workflow Run ↗︎.
Learn more about Supabase for Git ↗︎.

@BigSimmo
BigSimmo enabled auto-merge (squash) July 13, 2026 12:38
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2841afe3-a7ba-4990-87bb-22f11135c4c2

📥 Commits

Reviewing files that changed from the base of the PR and between 53672e2 and 6b24b66.

📒 Files selected for processing (4)
  • supabase/migrations/20260713102000_revoke_supabase_admin_default_privileges.sql
  • supabase/migrations/20260713103000_scrub_legacy_rag_query_text.sql
  • supabase/schema.sql
  • tests/supabase-schema.test.ts
💤 Files with no reviewable changes (1)
  • supabase/schema.sql
🚧 Files skipped from review as they are similar to previous changes (2)
  • supabase/migrations/20260713103000_scrub_legacy_rag_query_text.sql
  • tests/supabase-schema.test.ts

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added stricter structural validation for DOCX, XLSX, and PDF uploads (rejecting corrupt, unsafe, macro-enabled, zip-bomb, or truncated files).
    • Recent clinical queries are now owner-scoped, capped to five entries, with legacy unscoped history purged on load.
    • Improved accessibility for tool previews/links with clearer button labels.
    • Improved text search performance while preserving result accuracy.
  • Security

    • Hardened browser connection permissions via tighter CSP.
    • Scrubbed legacy stored RAG query text and strengthened database default privilege rules.
  • Tests

    • Expanded coverage for upload validation, recent-query storage, accessibility, CSP, and database safeguards.

Walkthrough

Changes

Database audit hardening

Layer / File(s) Summary
Index-friendly lexical retrieval
supabase/migrations/..., supabase/schema.sql, scripts/sql/lexical-rpc-parity-check.sql, tests/supabase-schema.test.ts, supabase/drift-manifest.json
Lexical retrieval separates chunk and title probes, preserves output scoring, and adds parity, plan, timing, and replay checks.
Database privilege and data-state hardening
supabase/migrations/..., supabase/schema.sql, tests/supabase-schema.test.ts, docs/process-hardening.md, supabase/drift-manifest.json
Function search paths, future privileges, legacy RAG text, and content constraints are updated and verified.

Upload structure validation

Layer / File(s) Summary
Binary structure validation
src/lib/upload-structure.ts, tests/upload-structure.test.ts
OOXML archives are checked for required parts, unsafe paths, macros, external relationships, and resource limits; PDFs require an EOF trailer.
Upload route integration and fixtures
src/app/api/upload/route.ts, tests/api-validation-contract.test.ts, tests/private-access-routes.test.ts
The route invokes structural validation after signature validation, and upload fixtures include valid PDF trailers.

Scoped recent-query storage

Layer / File(s) Summary
Recent-query storage utility
src/components/clinical-dashboard/recent-query-storage.ts, tests/recent-query-storage.test.ts
Owner-scoped session queries are validated and capped, while legacy keys are removed.
Dashboard recent-query integration
src/components/ClinicalDashboard.tsx, src/components/clinical-dashboard/global-search-shell.tsx, tests/ui-smoke.spec.ts
Dashboard components clear legacy state and load queries using authenticated or demo owner IDs.

Browser and UI hardening

Layer / File(s) Summary
Restricted browser connections
src/lib/security-headers.ts, tests/proxy.test.ts, tests/security-headers.test.ts
The CSP excludes the OpenAI origin from browser connect-src.
Accessible tool actions
src/components/tools-page-mockups/*, tests/ui-tools-collapse.spec.ts
Preview and open controls now expose explicit accessible labels.

Estimated code review effort: 4 (Complex) | ~60 minutes


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Verification Claims ❌ Error The PR text includes generic verification claims and checklist items, but not explicit 'Ran : passed' / 'Not run: reason' wording. Rewrite verification statements to name each exact command/check and its status, e.g. 'Ran npm run verify:pr-local: passed' or 'Not run: reason'.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 70.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (9 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the audit remediation focus across retrieval, privacy, upload, CSP, and accessibility.
Description check ✅ Passed The description follows the required template with Summary, Verification, Clinical Governance Preflight, and Notes, and provides substantive details.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Generated And Sensitive Files ✅ Passed Full branch diff has no secrets or forbidden artifacts; only code/docs/schema files changed, plus a justified tracked drift manifest and safe .env.example template.
Risky Git Or Deployment Actions ✅ Passed No force-push/reset/branch-deletion guidance found; live-apply items are explicitly confirmation-required, and the SQL harness is scratch-only.
Supabase Project And Schema Safety ✅ Passed PASS: edited files keep the live sjrfecxgysukkwxsowpy ref, and the DB changes are guarded by warnings, probes, assertions, and verification docs/tests.
Runtime And Package Manager Integrity ✅ Passed PR diff touches no package/runtime files; repo still pins npm@11.17.0, Node 24.x, engine-strict=true, and CI uses npm ci with package-lock.json.
Api Route Failure Handling ✅ Passed PASS: the new upload, RAG, provider, and ingestion paths all convert failures to explicit errors or fallbacks (400/429/503/504) and catch storage/parse issues; no unsafe branch found.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/audit-remediation-2026-07-13
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/audit-remediation-2026-07-13

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]
coderabbitai Bot previously requested changes Jul 13, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/ClinicalDashboard.tsx (1)

1177-1201: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Reimplements loadRecentQueries instead of calling it.

This effect duplicates the exact parse/filter/cap logic already implemented and tested in recent-query-storage.ts's loadRecentQueries, which was imported for global-search-shell.tsx but not here. Any future change to the shared helper (cap size, filtering rule) won't propagate to this copy.

♻️ Use the shared helper
-import { clearLegacyRecentQueries, demoRecentQueryOwnerId } from "`@/components/clinical-dashboard/recent-query-storage`";
+import {
+  clearLegacyRecentQueries,
+  demoRecentQueryOwnerId,
+  loadRecentQueries,
+} from "`@/components/clinical-dashboard/recent-query-storage`";
   useEffect(() => {
-    if (!answerThreadOwnerId) {
-      queueMicrotask(() => setRecentQueries([]));
-      return;
-    }
     let cancelled = false;
     const frame = window.requestAnimationFrame(() => {
-      try {
-        const stored = JSON.parse(
-          window.sessionStorage.getItem(`${recentQueryStorageKey}:${answerThreadOwnerId}`) ?? "[]",
-        );
-        if (Array.isArray(stored) && !cancelled) {
-          setRecentQueries(
-            stored.filter((item): item is string => typeof item === "string" && Boolean(item.trim())).slice(0, 5),
-          );
-        }
-      } catch {
-        if (!cancelled) setRecentQueries([]);
-      }
+      if (!cancelled) setRecentQueries(loadRecentQueries(answerThreadOwnerId));
     });
     return () => {
       cancelled = true;
       window.cancelAnimationFrame(frame);
     };
   }, [answerThreadOwnerId]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ClinicalDashboard.tsx` around lines 1177 - 1201, Update the
recent-query-loading useEffect in ClinicalDashboard to call the shared
loadRecentQueries helper from recent-query-storage.ts instead of duplicating
JSON parsing, filtering, and limiting logic. Preserve the existing
answerThreadOwnerId guard, animation-frame scheduling, cancellation handling,
and empty-state behavior while reusing the helper’s result.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/process-hardening.md`:
- Line 316: Update the “Legacy rag query text scrub (audit finding 5)”
documentation to cover all four migration checks: scrubbing rag_queries.query,
rag_queries.normalized_query, and rag_retrieval_logs, plus deletion of legacy
rag_response_cache rows. Expand the operator post-apply verification guidance
with the expected checks and outcomes for each affected table or operation.

In `@src/lib/upload-structure.ts`:
- Around line 39-45: The hasDangerousExternalRelationship function must detect
external relationships regardless of namespace prefixes or single- versus
double-quoted attributes. Replace the fragile tag regex with XML parsing, or
extend it to handle both forms, while preserving the hyperlink exemption; fail
conservatively when relationship XML cannot be safely parsed and add bypass
tests covering prefixed elements and single-quoted attributes.
- Around line 117-120: Update the PDF validation around the tail check in upload
structure parsing to require the final non-whitespace content to end with the
%%EOF marker, rather than accepting any occurrence in the tail. Preserve support
for trailing PDF whitespace, reject unfinished content where %%EOF appears
inside an object, and add a rejection test covering that case.
- Around line 94-96: Update the required-part validation around zip.file in the
upload structure flow to read/decompress the entry before accepting it. Handle
read or decompression failures by calling rejectUpload with the existing
package/part context, while preserving the current missing-entry rejection
behavior.
- Around line 55-62: Update the entry-path validation loop in the archive
handling logic to validate each JSZip entry’s original name, falling back to its
sanitized name when unavailable: use unsafeOriginalName ?? name rather than the
Object.keys(zip.files) key. Keep the existing entry-count check and rejectUpload
behavior unchanged.

In `@supabase/migrations/20260713103000_scrub_legacy_rag_query_text.sql`:
- Around line 20-51: Update the redaction checks in the migration statements for
rag_queries, rag_query_misses, rag_retrieval_logs, and rag_response_cache to
validate the complete token format defined by query-privacy.ts rather than only
the redacted-query: or redacted-cache: prefix. Reuse the exact query and cache
token shapes so only valid redacted values are preserved, while legacy
plaintext—including values sharing the prefix—is scrubbed or deleted.

In `@supabase/schema.sql`:
- Around line 4944-4948: Update the insufficient_privilege handler in the
default-privilege hardening block to preserve the warning details and then
re-throw the exception so deployment fails closed when hardening cannot be
applied. Apply the same re-throw behavior in migration
20260713102000_revoke_supabase_admin_default_privileges.sql, keeping the
existing operator follow-up message intact.

---

Outside diff comments:
In `@src/components/ClinicalDashboard.tsx`:
- Around line 1177-1201: Update the recent-query-loading useEffect in
ClinicalDashboard to call the shared loadRecentQueries helper from
recent-query-storage.ts instead of duplicating JSON parsing, filtering, and
limiting logic. Preserve the existing answerThreadOwnerId guard, animation-frame
scheduling, cancellation handling, and empty-state behavior while reusing the
helper’s result.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 84038bec-2ab9-46f4-8f53-90ec0c131af6

📥 Commits

Reviewing files that changed from the base of the PR and between ccf7334 and b89f915.

📒 Files selected for processing (26)
  • docs/process-hardening.md
  • scripts/sql/lexical-rpc-parity-check.sql
  • src/app/api/upload/route.ts
  • src/components/ClinicalDashboard.tsx
  • src/components/clinical-dashboard/global-search-shell.tsx
  • src/components/clinical-dashboard/recent-query-storage.ts
  • src/components/tools-page-mockups/split-pane-refined-mockups.tsx
  • src/components/tools-page-mockups/tools-page-mockup-page.tsx
  • src/lib/security-headers.ts
  • src/lib/upload-structure.ts
  • supabase/drift-manifest.json
  • supabase/migrations/20260713100000_index_friendly_lexical_retrieval.sql
  • supabase/migrations/20260713101000_pin_retrieval_owner_matches_v2_search_path.sql
  • supabase/migrations/20260713102000_revoke_supabase_admin_default_privileges.sql
  • supabase/migrations/20260713103000_scrub_legacy_rag_query_text.sql
  • supabase/migrations/20260713104000_validate_content_not_blank_constraints.sql
  • supabase/schema.sql
  • tests/api-validation-contract.test.ts
  • tests/private-access-routes.test.ts
  • tests/proxy.test.ts
  • tests/recent-query-storage.test.ts
  • tests/security-headers.test.ts
  • tests/supabase-schema.test.ts
  • tests/ui-smoke.spec.ts
  • tests/ui-tools-collapse.spec.ts
  • tests/upload-structure.test.ts

Comment thread docs/process-hardening.md Outdated
Comment thread src/lib/upload-structure.ts
Comment thread src/lib/upload-structure.ts Outdated
Comment thread src/lib/upload-structure.ts Outdated
Comment thread src/lib/upload-structure.ts
Comment thread supabase/migrations/20260713103000_scrub_legacy_rag_query_text.sql Outdated
Comment thread supabase/schema.sql
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 6 file(s) based on 7 unresolved review comments.

Files modified:

  • docs/process-hardening.md
  • src/lib/upload-structure.ts
  • supabase/migrations/20260713102000_revoke_supabase_admin_default_privileges.sql
  • supabase/migrations/20260713103000_scrub_legacy_rag_query_text.sql
  • supabase/schema.sql
  • tests/upload-structure.test.ts

Commit: fb3e3412d1073bdf016bdad472c67662a70f3307

The changes have been pushed to the claude/audit-remediation-2026-07-13 branch.

Time taken: 11m 40s

@BigSimmo

Copy link
Copy Markdown
Owner Author

@codex do a deep review of this PR. So perform a code review and fix all the identified issues in the comments for the issues you find. Find and fix

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b89f915102

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/upload-structure.ts Outdated
Comment thread src/lib/upload-structure.ts
Comment thread src/lib/upload-structure.ts Outdated
@github-actions

Copy link
Copy Markdown

@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

Fixed 6 file(s) based on 7 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@BigSimmo

Copy link
Copy Markdown
Owner Author

@codex please fix all failing CI tests for me

@BigSimmo

Copy link
Copy Markdown
Owner Author

@codex fix and address all comments with smallest possible fix and no regression

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 53672e2609

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/migrations/20260713103000_scrub_legacy_rag_query_text.sql
Comment thread supabase/migrations/20260713102000_revoke_supabase_admin_default_privileges.sql Outdated
@chatgpt-codex-connector

Copy link
Copy Markdown

Summary

  • Tightened OOXML upload admission so its compression-ratio guard now matches the extractor budget: 100:1 with the same 16 MB floor, avoiding files that pass upload but fail ingestion immediately. src/lib/upload-structure.tsL12-L15 src/lib/upload-structure.tsL83-L89
  • Anchored PDF structural validation so %%EOF must be the final meaningful trailer token, allowing only trailing PDF whitespace/NUL bytes. src/lib/upload-structure.tsL125-L133
  • Added a regression test for an OOXML archive that exceeds the extractor-aligned compression-ratio budget. tests/upload-structure.test.tsL187-L198
  • Committed the changes on the current branch with commit 2857e6a (fix: align upload structural guards with extractor) and created a PR via the PR tool.

Testing

  • npm ci — restored missing local dependencies; completed with 0 reported vulnerabilities.
  • npm run test -- tests/upload-structure.test.ts
  • node --max-old-space-size=8192 ./node_modules/eslint/bin/eslint.js src/lib/upload-structure.ts tests/upload-structure.test.ts --max-warnings 0

Notes

  • ⚠️ npm run test -- tests/upload-structure.test.ts initially could not run because the default shell resolved to Node v20.20.2 and dependencies were missing; verification was rerun successfully using local Node v24.15.0.

View task →

The auto-fix commit introduced three defects:

- 20260713102000 re-raised insufficient_privilege after the warning, turning
  the deliberate hosted degradation into a hard abort of the migration chain
  (schema.sql mirror too). Reverted with a comment stating the invariant, and
  the schema test now rejects any bare re-raise in the guard.
- 20260713103000's strict '^redacted-query:[0-9a-f]{64}$' check did not accept
  the migration's own 'redacted-query:legacy:<md5>' placeholders, so the
  completion assertion aborted on the very rows it had just scrubbed. The
  format check now accepts both valid shapes and stays idempotent on re-run.
- schema.sql changed without regenerating the drift manifest, failing the
  sha-pinned drift-detection test; the revert restores the manifest match.

Kept: the upload-structure hardening (namespaced Relationship tags, quote
variants, unsafeOriginalName, required-part decompression check) and its new
tests, and the expanded scrub documentation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai Bot previously requested changes Jul 13, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@supabase/migrations/20260713102000_revoke_supabase_admin_default_privileges.sql`:
- Line 45: Remove the unreachable duplicate raise statement from the exception
handler in the migration, and remove the matching duplicate from the
corresponding schema.sql replay block. Preserve the preceding re-raise and keep
both definitions consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 15dcd02a-c2b3-4c6e-ac0b-8b6f88f1342c

📥 Commits

Reviewing files that changed from the base of the PR and between b89f915 and 53672e2.

📒 Files selected for processing (8)
  • docs/process-hardening.md
  • src/components/ClinicalDashboard.tsx
  • src/lib/upload-structure.ts
  • supabase/migrations/20260713102000_revoke_supabase_admin_default_privileges.sql
  • supabase/migrations/20260713103000_scrub_legacy_rag_query_text.sql
  • supabase/schema.sql
  • tests/ui-smoke.spec.ts
  • tests/upload-structure.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • tests/ui-smoke.spec.ts
  • tests/upload-structure.test.ts
  • src/components/ClinicalDashboard.tsx
  • supabase/migrations/20260713103000_scrub_legacy_rag_query_text.sql
  • docs/process-hardening.md
  • supabase/schema.sql
  • src/lib/upload-structure.ts

Comment thread supabase/migrations/20260713102000_revoke_supabase_admin_default_privileges.sql Outdated
…ation

Resolves the schema.sql conflict to the no-re-raise version: the re-raise
(applied twice via the GitHub suggestion UI — the second statement was
unreachable) would abort the whole live migration chain on hosted Supabase
in exactly the scenario the guard is designed to degrade through, blocking
the privacy scrub and constraint-validation migrations behind it. The
lockdown remains probe-verified where it can apply, with the documented
operator follow-up where it cannot, and the schema test now rejects a bare
re-raise in this guard.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@BigSimmo

Copy link
Copy Markdown
Owner Author

Heads-up on two fix-forward commits after the CodeRabbit auto-fix round:

  1. Reverted the raise; re-raise in 20260713102000 (it was also applied twice via the suggestion UI — the second statement was unreachable). The guard is designed to degrade to a WARNING when hosted postgres cannot act for supabase_admin: a re-raise there aborts the entire live migration chain, blocking the privacy scrub (20260713103000) and constraint validation (20260713104000) behind it. The lockdown is still probe-verified wherever it can apply (CI replay, scratch replay, superuser), and the documented operator follow-up covers hosted. A schema test now rejects any bare re-raise in this guard.
  2. Fixed the strict redaction-format check so it accepts the migration's own redacted-query:legacy:<md5> placeholders — as auto-fixed, the completion assertion aborted on the very rows the migration had just scrubbed. The check now accepts both valid shapes (redacted-query:<64-hex> and redacted-query:legacy:<32-hex>), keeping CodeRabbit's stricter-than-prefix matching and idempotent re-runs.
  3. The auto-fix also changed schema.sql without regenerating the drift manifest (sha-pinned by tests/drift-detection.test.ts), which is what was failing CI; restoring the guard resolves the manifest match.

Kept from the auto-fix: all the upload-structure.ts hardening (namespaced Relationship tags, quote variants, unsafeOriginalName, required-part decompression check) plus its new tests, and the expanded scrub documentation.

🤖 Generated with Claude Code

BigSimmo added a commit that referenced this pull request Jul 13, 2026
…TTL (PT-16) (#597)

* fix(privacy): clear recents at the session boundary and bound thread TTL (PT-16)

Follow-up to #582's owner-scoped recents: sign-out and session expiry
now clear every owner-scoped recents key (plus legacy residue) so the
next person on a shared workstation cannot inherit recent clinical
question text, and persisted answer threads carry a savedAt stamp that
expires after 12h so raw query/answer text cannot idle indefinitely in
long-lived tabs. Legacy payloads without the stamp stay loadable once
and are stamped on next save.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(auth): purge private recents on passive sign-out

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@BigSimmo
BigSimmo deleted the claude/audit-remediation-2026-07-13 branch July 13, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant